package controllers

import (
	"cronjob/jobs"
	"cronjob/models"

	"github.com/gorhill/cronexpr"

	"strconv"
	"strings"
	"time"

	"github.com/astaxie/beego"
)

type TaskController struct {
	BaseController
}

// 任务列表
func (this *TaskController) List() {

	this.Data["taskGroup"] = taskGroupLists(this.taskGroups, this.userID)
	this.Data["pageTitle"] = "任务管理"
	this.display()
}

//任务审核
func (this *TaskController) Auditlist() {
	this.Data["pageTitle"] = "任务审核"
	this.display()
}

//ajax 加载任务列表
func (this *TaskController) Table() {
	//当前第几页
	page, err := this.GetInt("page")
	if err != nil {
		page = 1
	}

	//每页显示几个
	limit, err := this.GetInt("limit")
	if err != nil {
		limit = 5
	}

	this.pageSize = limit
	filters := make([]interface{}, 0)
	// arr := []int{0, 1, 2, 3} //删除的不显示
	// filters = append(filters, "status__in", arr)

	groupId, _ := this.GetInt("group_id", 0)

	if groupId == 0 {
		//  当前不是超级管理员

		if this.userID != 1 {
			//分割管理的groupIds
			groups := strings.Split(this.taskGroups, ",")
			//将字符串类型的任务分组转换为整形的任务分组
			groupIds := make([]int, 0)
			for _, v := range groups {
				id, _ := strconv.Atoi(v)
				groupIds = append(groupIds, id)
			}
			filters = append(filters, "group_id__in", groupIds)
		}
	} else {
		filters = append(filters, "group_id", groupId)
	}

	//接受服务名搜索
	taskName := strings.TrimSpace(this.GetString("task_name"))
	if taskName != "" {
		filters = append(filters, "task_name__icontains", taskName)
	}

	status, _ := this.GetInt("status")

	if status == 2 {
		statusIds := []int{2, 3}
		filters = append(filters, "status__in", statusIds)
	} else {
		statusIds := []int{0, 1}
		filters = append(filters, "status__in", statusIds)
	}

	//查询数据
	result, count := models.TaskGetList(page, this.pageSize, filters...)

	StatusText := []string{
		"<font color='red'><i class='fa fa-minus-square'></i></font>",
		"<font color='green'><i class='fa fa-check-square'></i></font>",
		"<font color='orange'><i class='fa fa-question-circle'></i></font>",
		"<font color='red'><i class='fa fa-times-circle'></i></font>",
	}

	list := make([]map[string]interface{}, len(result))

	//查询所有分组
	taskGroup := taskGroupLists(this.taskGroups, this.userID)

	for k, val := range result {
		row := make(map[string]interface{})
		row["id"] = val.Id

		groupName := "默认分组"
		if name, ok := taskGroup[val.GroupId]; ok {
			groupName = name
		}

		row["task_name"] = StatusText[val.Status] + groupName + " " + val.TaskName
		row["description"] = val.Description

		//根据任务id获取当前任务执行对象
		e := jobs.GetEnteryById(val.Id)

		if e == nil { //任务未加入当前调度中心
			row["next_time"] = "-"
			if val.PrevTime > 0 {
				row["pre_time"] = beego.Date(time.Unix(val.PrevTime, 0), "Y-m-d H:i:s")
			} else {
				row["pre_time"] = "-"
			}
		} else {
			row["next_time"] = beego.Date(e.Next, "Y-m-d H:i:s")
			if e.Prev.Unix() > 0 {
				row["pre_time"] = beego.Date(e.Prev, "Y-m-d H:i:s")
			} else {
				row["pre_time"] = beego.Date(time.Unix(val.PrevTime, 0), "Y-m-d H:i:s")
			}
		}

		row["execute_times"] = val.ExecuteTimes
		list[k] = row
	}
	this.ajaxList("成功", MSG_OK, count, list)
}

// detail
func (this *TaskController) Detail() {
	// 获取任务id
	id, _ := this.GetInt("id")

	//根据任务id查询任务
	task, err := models.TaskGetById(id)

	if err != nil {
		return
	}

	this.Data["task"] = task

	TextStatus := []string{
		"<font color='red'><i class='fa fa-minus-square'></i> 暂停</font>",
		"<font color='green'><i class='fa fa-check-square'></i> 运行中</font>",
		"<font color='orange'><i class='fa fa-question-circle'></i> 待审核</font>",
		"<font color='red'><i class='fa fa-times-circle'></i> 审核失败</font>",
	}
	//-1：删除  0：停用  1：启用  3：不通过 2:待审核
	this.Data["TextStatus"] = TextStatus[task.Status]

	//serverName
	//服务器名称
	serverName := "本地服务器"
	if task.ServerId == 0 {
		serverName = "本地服务器"
	} else if task.ServerId > 0 {
		server, err := models.TaskSeverGetById(task.ServerId)
		if err == nil {
			serverName = server.ServerName
		}
	}
	this.Data["serverName"] = serverName

	// 分组名称
	GroupName := "未知"
	if task.GroupId > 0 {
		ginfo, err := models.GroupGetId(task.GroupId)
		if err == nil {
			GroupName = ginfo.GroupName
		}
	}

	this.Data["GroupName"] = GroupName

	//被通知人的id不是默认值并且不是空字符串
	if task.NotifyUserIds != "0" && task.NotifyUserIds != "" {
		// this.Data["adminInfo"] = // jobs.AllAdminInfo(task.NotifyUserIds)
		// this.Data["adminInfo"] = task.NotifyUserIds
		this.Data["adminInfo"] = models.AdminGetByIds(task.NotifyUserIds)
	} else {
		this.Data["adminInfo"] = []*models.Admin{}
	}

	//任务创建时间
	this.Data["CreateTime"] = beego.Date(time.Unix(task.CreateTime, 0), "Y-m-d H:i:s")

	//任务创建人
	CreateName := "未知"
	if task.CreateId != 0 {
		ainfo, err := models.AdminGetById(task.CreateId)
		if err == nil {
			CreateName = ainfo.LoginName
		}
	}

	this.Data["CreateName"] = CreateName

	//修改时间
	this.Data["UpdateTime"] = beego.Date(time.Unix(task.UpdateTime, 0), "Y-m-d H:i:s")

	// 修改人
	UpdateName := "未知"
	if task.UpdateId != 0 {
		ainfo, err := models.AdminGetById(task.UpdateId)
		if err == nil {
			UpdateName = ainfo.LoginName
		}
	}
	this.Data["UpdateName"] = UpdateName

	// 文章标题
	this.Data["pageTitle"] = "任务详情"

	this.display()
}

// 测试
func (this *TaskController) AjaxRun() {
	// 获取任务id
	id, _ := this.GetInt("id")
	//根据任务id查询任务
	task, err := models.TaskGetById(id)
	if err != nil {
		this.ajaxMsg("没有该任务，无法执行", MSG_ERR)
	}

	//根据任务task
	job, err := jobs.NewJobFromTask(task)

	//测试任务执行
	job.Run()
	this.ajaxMsg("任务执行成功", MSG_OK)
}

// 状态设置通过状态
func (this *TaskController) Ajaxbatchaudit() {
	ids := this.GetString("ids")
	idsArr := strings.Split(ids, ",")

	if len(idsArr) < 1 {
		this.ajaxMsg("请选择任务", MSG_ERR)
	}

	for _, v := range idsArr {
		id, _ := strconv.Atoi(v)
		if id < 0 {
			continue
		}
		changeStatus(id, 0, this.userID)
	}
	this.ajaxMsg("设置成功", MSG_ERR)
}

func (this *TaskController) Ajaxbatchnopass() {
	ids := this.GetString("ids")
	idsArr := strings.Split(ids, ",")

	if len(idsArr) < 1 {
		this.ajaxMsg("请选择任务", MSG_ERR)
	}

	for _, v := range idsArr {
		id, _ := strconv.Atoi(v)
		if id < 0 {
			continue
		}
		changeStatus(id, 3, this.userID)
	}
	this.ajaxMsg("设置成功", MSG_ERR)
}

func (this *TaskController) Ajaxdel() {
	id, _ := this.GetInt("id")

	if id < 0 {
		this.ajaxMsg("", MSG_ERR)
	}
	task, err := models.TaskGetById(id)

	if err != nil {
		this.ajaxMsg("任务不存在", MSG_ERR)
	}
	task.UpdateTime = time.Now().Unix()
	task.UpdateId = this.userID
	task.Status = -1

	if ok := task.Update(); ok != nil {
		this.ajaxMsg("任务不存在", MSG_ERR)
	}
	this.ajaxMsg("删除成功", MSG_OK)
}

// 更改任务的状态
func changeStatus(id int, status int, userId int) bool {
	if id < 0 {
		return false
	}

	task, err := models.TaskGetById(id)

	if err != nil {
		return false
	}

	task.UpdateTime = time.Now().Unix()
	task.UpdateId = userId
	task.Status = status

	if ok := task.Update(); ok != nil {
		return false
	}
	return true
}

// 任务编辑
func (this *TaskController) Edit() {
	id, _ := this.GetInt("id")
	//根据任务id查询任务
	task, err := models.TaskGetById(id)
	if err != nil {
		this.ajaxMsg("没有该任务，无法执行", MSG_ERR)
	}

	if task.Status == 1 {
		this.ajaxMsg("任务在运行。不能编辑", MSG_ERR)

	}
	this.Data["task"] = task

	//任务分组 taskGroup
	this.Data["taskGroup"] = taskGroupLists(this.taskGroups, this.userID)

	//服务器分组 serverGroup

	serverGroup := serverLists(this.serverGroups, this.userID)

	this.Data["serverGroup"] = serverGroup

	//前端模版显示是否超级管理员
	if this.userID == 1 {
		this.Data["isAdmin"] = 1
	} else {
		this.Data["isAdmin"] = 6
	}

	// 管理员信息
	// Filters := make([]interface{}, 0)
	// Filters = append(Filters, "status", 1)
	// Result, _ := models.AdminGetList(1, 100, Filters)

	this.Data["adminInfo"] = models.AdminGetByIds("")

	var notifyUserIds []int
	if task.NotifyUserIds != "" && task.NotifyUserIds != "0" {
		notifyUserStr := strings.Split(task.NotifyUserIds, ",")
		for _, v := range notifyUserStr {
			userId, _ := strconv.Atoi(v)
			notifyUserIds = append(notifyUserIds, userId)
		}
	}

	this.Data["notify_user_ids"] = notifyUserIds
	this.display()
}

// 新增任务
func (this *TaskController) Add() {
	this.Data["taskGroup"] = taskGroupLists(this.taskGroups, this.userID)

	//服务器分组 serverGroup

	serverGroup := serverLists(this.serverGroups, this.userID)

	this.Data["serverGroup"] = serverGroup

	//前端模版显示是否超级管理员
	if this.userID == 1 {
		this.Data["isAdmin"] = 1
	} else {
		this.Data["isAdmin"] = 6
	}

	// 管理员信息
	// Filters := make([]interface{}, 0)
	// Filters = append(Filters, "status", 1)
	// Result, _ := models.AdminGetList(1, 100, Filters)

	this.Data["adminInfo"] = models.AdminGetByIds("")

	this.display()
}

// 修改保存
func (this *TaskController) AjaxSave() {

	//获取任务id
	id, _ := this.GetInt("id")

	//当id等于0时，添加数据
	if id == 0 {
		task := new(models.Task)

		task.TaskName = strings.TrimSpace(this.GetString("task_name"))
		task.GroupId, _ = this.GetInt("group_id")
		task.ServerId, _ = this.GetInt("server_id")
		task.Description = strings.TrimSpace(this.GetString("description"))
		task.Concurrent, _ = this.GetInt("concurrent")
		task.CronSpec = strings.TrimSpace(this.GetString("cron_spec"))
		task.Command = strings.TrimSpace(this.GetString("command"))
		task.Timeout, _ = this.GetInt("timeout")
		task.IsNotify, _ = this.GetInt("is_notify")
		task.NotifyType, _ = this.GetInt("notify_type")
		task.NotifyUserIds = strings.TrimSpace(this.GetString("notify_user_ids"))
		//更新人和更新时间

		if task.TaskName == "" {
			this.ajaxMsg("任务名称不能为空", MSG_ERR)
		}

		if task.CronSpec == "" {
			this.ajaxMsg("时间表达式不能为空", MSG_ERR)
		}

		if task.Command == "" {
			this.ajaxMsg("命令不能为空", MSG_ERR)
		}

		task.CreateId = this.userID
		task.CreateTime = time.Now().Unix()

		task.UpdateId = this.userID
		task.UpdateTime = time.Now().Unix()

		//判断是否是超级管理员
		if this.userID == 1 {
			task.Status = 0
		} else {
			task.Status = 2
		}

		// 检查命令是非法
		flag := checkCommand(task.Command)

		if flag {
			this.ajaxMsg("含有禁止命令！", MSG_ERR)
		}

		if _, err := cronexpr.Parse(task.CronSpec); err != nil {
			this.ajaxMsg("时间表达式不合法", MSG_ERR)
		}

		if _, err := models.TaskAdd(task); err != nil {
			this.ajaxMsg("复制失败", MSG_ERR)
		}

		this.ajaxMsg("复制成功", MSG_ERR)
	} else {
		//根据任务id查询任务
		task, err := models.TaskGetById(id)
		if err != nil {
			this.ajaxMsg("任务不存在", MSG_ERR)
		}

		task.TaskName = strings.TrimSpace(this.GetString("task_name"))
		task.GroupId, _ = this.GetInt("group_id")
		task.ServerId, _ = this.GetInt("server_id")
		task.Description = strings.TrimSpace(this.GetString("description"))
		task.Concurrent, _ = this.GetInt("concurrent")
		task.CronSpec = strings.TrimSpace(this.GetString("cron_spec"))
		task.Command = strings.TrimSpace(this.GetString("command"))
		task.Timeout, _ = this.GetInt("timeout")
		task.IsNotify, _ = this.GetInt("is_notify")
		task.NotifyType, _ = this.GetInt("notify_type")
		task.NotifyUserIds = strings.TrimSpace(this.GetString("notify_user_ids"))
		//更新人和更新时间
		task.UpdateId = this.userID
		task.UpdateTime = time.Now().Unix()

		//判断是否是超级管理员
		if this.userID == 1 {
			task.Status = 0
		} else {
			task.Status = 2
		}

		// 检查命令是非法
		flag := checkCommand(task.Command)

		if flag {
			this.ajaxMsg("含有禁止命令！", MSG_ERR)
		}

		if _, err := cronexpr.Parse(task.CronSpec); err != nil {
			this.ajaxMsg("时间表达式不合法", MSG_ERR)
		}

		if err := task.Update(); err != nil {
			this.ajaxMsg("修改失败", MSG_ERR)
		}

		this.ajaxMsg("修改成功", MSG_OK)
	}

}

// 复制任务
func (this *TaskController) Copy() {
	//获取任务id
	id, _ := this.GetInt("id")
	//根据任务id查询任务
	task, err := models.TaskGetById(id)
	if err != nil {
		this.ajaxMsg("任务不存在", MSG_ERR)
	}

	this.Data["task"] = task

	//任务分组 taskGroup
	this.Data["taskGroup"] = taskGroupLists(this.taskGroups, this.userID)

	//服务器分组 serverGroup

	serverGroup := serverLists(this.serverGroups, this.userID)

	this.Data["serverGroup"] = serverGroup

	//前端模版显示是否超级管理员
	if this.userID == 1 {
		this.Data["isAdmin"] = 1
	} else {
		this.Data["isAdmin"] = 6
	}

	// 管理员信息
	// Filters := make([]interface{}, 0)
	// Filters = append(Filters, "status", 1)
	// Result, _ := models.AdminGetList(1, 100, Filters)

	this.Data["adminInfo"] = models.AdminGetByIds("")
	this.display()
}

//  启动 任务启动
func (this *TaskController) AjaxBatchStart() {
	// 接受要启动任务的id
	ids := this.GetString("ids")

	// 分割成数据
	idarr := strings.Split(ids, ",")

	if len(idarr) < 1 {
		this.ajaxMsg("请选择要操作的任务", MSG_ERR)
	}

	for _, idval := range idarr {
		id, _ := strconv.Atoi(idval)

		//判断id是否合法
		if id < 1 {
			continue
		}

		if task, err := models.TaskGetById(id); err == nil {
			// 根据task 创建job
			job, err := jobs.NewJobFromTask(task)
			//判断是否创建成功
			if err == nil {
				// 将task 添加到任务重
				jobs.AddJob(task.CronSpec, job)

				//修改为启动状态
				task.Status = 1
				task.Update("Status")
			}
		}
	}

	this.ajaxMsg("启动成功", MSG_OK)
}

//  启动 暂停
func (this *TaskController) AjaxBatchPause() {
	// 接受要启动任务的id
	ids := this.GetString("ids")

	// 分割成数据
	idarr := strings.Split(ids, ",")

	if len(idarr) < 1 {
		this.ajaxMsg("请选择要操作的任务", MSG_ERR)
	}

	for _, idval := range idarr {
		id, _ := strconv.Atoi(idval)

		//判断id是否合法
		if id < 1 {
			continue
		}
		// 在任务队列重删除
		jobs.RomoveJob(id)

		//修改执行状态
		if task, err := models.TaskGetById(id); err == nil {

			//更改状态为禁止状态
			task.Status = 0
			// 更新
			task.Update("Status")

		}
	}

	this.ajaxMsg("启动成功", MSG_OK)
}

// 检查命令是非包含有禁用命令
// 是true     否 false
func checkCommand(command string) bool {
	filters := make([]interface{}, 0)
	//正常的命令
	filters = append(filters, "status", 0)

	//分页查询
	ban, _ := models.BanGetList(1, 10000, filters...)

	for _, v := range ban {
		// if strings.Contains()
		if strings.Contains(v.Code, command) || strings.Contains(command, v.Code) {
			return true
		}
	}
	return false
}
